﻿using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Esponce.Common;
using Esponce.QRCode;
using Microsoft.Win32;

namespace Esponce.Models
{
	public class DecodeViewModel : INotifyPropertyChanged
	{
		#region Constructor
		public DecodeViewModel()
		{
#if DEBUG
			if (Settings.IsDesignMode)
			{
				this.Content = "hello world";
				this.ImagePath = @"d:\temp\image.png";
			}
#endif
		}
		#endregion

		#region Public properties
		public string Content
		{
			get
			{
				return this.content;
			}
			set
			{
				if (this.content != value)
				{
					this.content = value;
					OnPropertyChanged("Content");
				}
			}
		}
		private string content;

		public ImageSource ImageSource
		{
			get
			{
				return this.imageSource;
			}
			set
			{
				if (this.imageSource != value)
				{
					this.imageSource = value;
					OnPropertyChanged("ImageSource");
				}
			}
		}
		private ImageSource imageSource;

		public string ImagePath
		{
			get
			{
				return this.imagePath;
			}
			set
			{
				if (this.imagePath != value)
				{
					this.imagePath = value;
					OnPropertyChanged("ImagePath");
				}
			}
		}
		private string imagePath;

		public string PreviewUrl
		{
			get
			{
				return App.ViewModel.CreateClient().UriBuilder.BuildDecodeUrl();
			}
		}

		public double PreviewOpacity
		{
			get
			{
				return this.IsLoading ? 0.2 : 1.0;
			}
		}

		public bool IsLoading
		{
			get
			{
				return this.isLoading;
			}
			set
			{
				if (this.isLoading != value)
				{
					this.isLoading = value;
					OnPropertyChanged("IsLoading");
					OnPropertyChanged("PreviewOpacity");
				}
			}
		}
		private bool isLoading;
		#endregion

		#region Public methods
		public void Browse()
		{
			OpenFileDialog dialog = new OpenFileDialog();
			dialog.Filter = "Image (*.png)|*.png";
			dialog.DefaultExt = "*.png";

			if (dialog.ShowDialog() == true)
			{
				LoadImage(dialog.FileName);
			}
		}

		public void Decode()
		{
			try
			{
				//Start the loading animation for better UX
				this.IsLoading = true;

				string path = this.ImagePath;
				var stream = File.OpenRead(path);

				App.Logger.WriteLine("POST " + this.PreviewUrl);

				//Make an API request
				var client = App.ViewModel.CreateClient();
				client.DecodeCompleted += (sender, e) =>
				{
					//Stop the loading animation
					this.IsLoading = false;

					if (e.Error == null)
					{
						//Display result
						this.Content = e.Content;

						App.Logger.WriteLine(string.Format("QR Code decoded. Rate limit: {0} requests remaining out of {1}", client.RateLimitRemaining, client.RateLimitTotal));
						App.Logger.WriteLine(string.Format("Version: {0}, Error Correction Level: {1}, Dimension: {2}, Capacity: {3}, Length: {4}", e.Version, e.ErrorCorrection, e.Dimension, e.Capacity, e.Length));
					}
					else
					{
						//Report error to the console
						App.Logger.Log(e.Error);
					}
				};
				client.DecodeAsync(stream);
			}
			catch (Exception ex)
			{
				App.Logger.Log(ex);
			}
		}

		public void LoadImage(string path)
		{
			this.ImagePath = path;

			try
			{
				this.ImageSource = new BitmapImage(new Uri(path, UriKind.Absolute));
			}
			catch
			{
				this.ImageSource = null;
				App.Logger.Log(new Exception("Cannot render the image preview."));
			}
		}
		#endregion

		#region INotifyPropertyChanged Members
		public event PropertyChangedEventHandler PropertyChanged;
		protected virtual void OnPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}
		#endregion
	}
}
